#ifndef HIDE_PROCESS_SSDT_H_H
#define HIDE_PROCESS_SSDT_H_H

#include "HideProcess.h"

typedef (*QuerySystemInformation)(
								  IN ULONG systemInformationClass,
								  IN PVOID systemInformation,
								  IN ULONG systemInformationLength,
								  OUT PULONG returnLength);


class HideProcessSSDT : public HideProcess
{
	friend class HideProcess;
public:
	~HideProcessSSDT();
	bool isHide(UNICODE_STRING& processName) const;
	bool startHide();
	void stopHide();
	QuerySystemInformation GetQuery() const {
		return m_OrignalQueSysInfo;
	}
private:
	HideProcessSSDT(size_t listMaxSize = 50);
	size_t getSysCallIndex(PVOID functionAddress);
	PVOID hookSysCall(PVOID functionAddress, PVOID hookFunctionAddress);
	void unhookSysCall(PVOID functionAddress, PVOID orginalFunctionAddress);
private:
	PMDL m_SSDTMdl;
	PVOID *m_MappedSSDT;
	QuerySystemInformation m_OrignalQueSysInfo;
};

struct ServiceDescriptorEntry
{
	unsigned int *ServicceTableBase;
	unsigned int *ServiceCounterTableBase;
	unsigned int NumberOfServices;
	unsigned char *ParamTableBase;
};

struct SystemThread
{
	LARGE_INTEGER KernelTime;
	LARGE_INTEGER UserTime;
	LARGE_INTEGER CreateTime;
	ULONG	WaitTime;
	PVOID	StartAddress;
	CLIENT_ID ClientIs;
	KPRIORITY Priority;
	KPRIORITY BasePriority;
	ULONG	ContextSwitchCount;
	ULONG	ThreadState;
	KWAIT_REASON WaitReason;
};

struct SystemProcess 
{
	ULONG	NextEntryDelta;
	ULONG	ThreadCount;
	ULONG	Reserved[6];
	LARGE_INTEGER	CreateTime;
	LARGE_INTEGER	UserTime;
	LARGE_INTEGER	KernelTime;
	UNICODE_STRING	ProcessName;
	KPRIORITY	BasePriority;
	ULONG	ProcessId;
	ULONG	InheritedFromProcessId;
	ULONG	HandleCount;
	ULONG	Reserved2[2];
	VM_COUNTERS	VmCounters;
	IO_COUNTERS	IoCounters;
	SystemThread Threads[1];
};

#endif